#include "dxgame.h"
#include "logger.h"

using namespace std;

DXGame::DXGame() : frameRate(0)
{ }

DXGame::DXGame(HINSTANCE hInst, const char* nameWnd, int w, int h, DWORD frame) 
							: lpWndClassName("Game2DClass"), lpWndName(nameWnd), frameRate(frame)
{	
    pGraphic =	NULL;
    pInput = NULL;
    pSound = NULL;
    hInstance = hInst;
    hWnd = NULL;
    widthScreen = w;
    heightScreen = h;
}

void DXGame::Run()
{	
    if (!Init())
        return;
    if (!LoadContent())
        return;	
    MSG msg;
    DWORD time_per_frame = 1000/frameRate;
    DWORD prevTime = GetTickCount();
    //Loop game
    while (true)
    {	
        if (PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE))
        {	
            if (!GetMessage(&msg, NULL, 0, 0))
                break;
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
        DWORD nowTime = GetTickCount();
        DWORD gameTime = nowTime - prevTime;
        if (gameTime >= time_per_frame)
        {	
            prevTime = nowTime;
            pInput->GetState();
            Update(gameTime);
            Render(gameTime);
            if (IsGameOver() == true)
                break;
        }	
        else
            Sleep(time_per_frame - gameTime);
    }
    return;
}

DXGame::~DXGame()
{	
    if (pSound != NULL)
        delete pSound;

    if (pInput != NULL)
        delete pInput;
        
    if (pGraphic != NULL)
        delete pGraphic;

    if (hWnd != NULL)
        DestroyWindow(hWnd);

    UnregisterClass(lpWndClassName, hInstance);
}

LRESULT CALLBACK DXGame::WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{	
    switch(uMsg)
    {	
        case WM_DESTROY:
            PostQuitMessage(0);
            break;
    }
    return DefWindowProc(hWnd, uMsg, wParam, lParam);
}



bool DXGame::Init()
{	
    //Init Window
    WNDCLASSEX wcex;
    wcex.cbSize = sizeof(WNDCLASSEX);
    wcex.style = CS_CLASSDC;
    wcex.lpfnWndProc = (WNDPROC)(&DXGame::WindowProc);
    wcex.cbClsExtra = 0;
    wcex.cbWndExtra = 0;
    wcex.hInstance = hInstance;
    wcex.hIcon = NULL; //LoadIcon(hInstance, MAKEINTRESOURCE(IDI_BREAKOUT_ICON));
    wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
    wcex.hbrBackground = NULL;
    wcex.lpszMenuName = NULL;
    wcex.lpszClassName = lpWndClassName;
    wcex.hIconSm = NULL;
    if (!RegisterClassEx(&wcex))
    {
        (Logger::GetLogger("DXGame")).Error("Can't register class windows!");
        return false;
    }
    hWnd = CreateWindow(lpWndClassName,
                        lpWndName, 
                        WS_OVERLAPPED, 
                        CW_USEDEFAULT, 
                        CW_USEDEFAULT,
                        widthScreen, 
                        heightScreen, 
                        NULL, 
                        NULL, 
                        hInstance, 
                        NULL);
    if (hWnd == NULL)
    {
        (Logger::GetLogger("DXGame")).Error("Can't create handle windows!");
        return false;
    }
    ShowWindow(hWnd, SW_SHOWDEFAULT);
    UpdateWindow(hWnd);

    //Create graphic manager
    if ((pGraphic = new DXGameGraphic(hWnd, widthScreen, heightScreen)) == NULL)
    {
        (Logger::GetLogger("DXGame")).Error("Can't create game graphic!");
        return false;
    }
    if (!pGraphic->Init())
    {
        (Logger::GetLogger("DXGame")).Error("Can't init game graphic!");
        return false;
    }

    //Create input manager
    if ((pInput = new DXGameInput(hWnd)) == NULL)
    {
        (Logger::GetLogger("DXGame")).Error("Can't create game input!");
        return false;
    }
    if (!pInput->Init())
    {
        (Logger::GetLogger("DXGame")).Error("Can't init game input!");
        return false;
    }

    //Create sound manager
    /*if ((pSound = new DXGameSound()) == NULL)
    {
        (Logger::GetLogger("DXGame")).Error("Can't create game sound!");
        return false;
    }
    if (!pSound->Init())
    {
        (Logger::GetLogger("DXGame")).Error("Can't init game sound!");
        return false;
    }*/
    return true;
}
